﻿using System;
using System.Collections.Generic;
using System.Linq;
using Cesave.Domain.Core.Specification;
using Cesave.Domain.PermisosModule.Contracts.Agentes;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.CrossCutting.Logging;
using Cesave.Infrastructure.Data.Core;
using Cesave.Infrastructure.Data.PermisosModule.Context;

namespace Cesave.Infrastructure.Data.PermisosModule.Repositories
{
	/// <summary>
	/// 
	/// </summary>
	public class AgenteRepository
		: GenericRepositoryEx<Agente>, IAgenteRepository
	{
		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="traceManager"></param>
		public AgenteRepository(IPermisosModuleContext context, ITraceManager traceManager)
			: base(context, traceManager)
		{
		}

		#endregion

		#region IAgenteRepository Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="agentesByJuntaSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Agente> FindAgentesByJuntaSpecification(AgentesByJuntaSpecification agentesByJuntaSpecification)
		{
			if (agentesByJuntaSpecification == null)
				throw new ArgumentNullException("agentesByJuntaSpecification");
			return GetFilteredElements(agentesByJuntaSpecification.SatisfiedBy(), agente => agente.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="agentesByJuntaSpecification"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public IEnumerable<Agente> FindAgentesByJuntaAndStatusSpecification(AgentesByJuntaSpecification agentesByJuntaSpecification, bool status = true)
		{
			if (agentesByJuntaSpecification == null)
				throw new ArgumentNullException("agentesByJuntaSpecification");
			Specification<Agente> agentesSpecification = new TrueSpecification<Agente>();
			agentesSpecification &= agentesByJuntaSpecification;
			agentesSpecification &= new AgentesByStatusSpecification(status);
			return GetFilteredElements(agentesSpecification.SatisfiedBy(), agente => agente.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="agentesByAclSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Agente> FindAgentesByAclSpecification(AgentesByAclSpecification agentesByAclSpecification)
		{
			if (agentesByAclSpecification == null)
				throw new ArgumentNullException("agentesByAclSpecification");
			return GetFilteredElements(agentesByAclSpecification.SatisfiedBy(), agente => agente.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="agenteByGuidSpecification"></param>
		/// <returns></returns>
		public Agente FindAgenteByGuidSpecification(AgenteByGuidSpecification agenteByGuidSpecification)
		{
			if (agenteByGuidSpecification == null)
				throw new ArgumentNullException("agenteByGuidSpecification");
			return GetBySpec(agenteByGuidSpecification).FirstOrDefault();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="agenteByUsuarioSpecification"></param>
		/// <returns></returns>
		public Agente FindAgenteByUsuarioSpecification(AgenteByUsuarioSpecification agenteByUsuarioSpecification)
		{
			if (agenteByUsuarioSpecification == null)
				throw new ArgumentNullException("agenteByUsuarioSpecification");
			return GetBySpec(agenteByUsuarioSpecification).FirstOrDefault();
		}

		#endregion
	}
}
